﻿using System;
using System.Diagnostics;

namespace Utilities
{
    /// <summary>
    /// Verifies a precondition
    /// </summary>
    public static class PreCondition
    {
        /// <summary>
        /// Throws an invalid operation exception when the condition evaluates to false
        /// </summary>
        /// <param name="condition">The condition to test</param>
        /// <param name="message">The message to output when the condition is not true</param>
        /// <param name="traceSource">The source to log the error</param>
        public static void RequireTrue(bool condition, string message, TraceSource traceSource = null)
        {
            if (!condition)
            {
                if (traceSource != null)
                {
                    traceSource.LogError(message);
                }

                throw new InvalidOperationException(message);
            }
        }

        /// <summary>
        /// Throws an invalid operation exception when the condition evaluates to true
        /// </summary>
        /// <param name="condition">The condition to test</param>
        /// <param name="message">The message to output when the condition is not true</param>
        /// <param name="traceSource">The source to log the error</param>
        public static void RequireFalse(bool condition, string message, TraceSource traceSource = null)
        {
            if (condition)
            {
                if (traceSource != null)
                {
                    traceSource.LogError(message);
                }

                throw new InvalidOperationException(message);
            }
        }

        /// <summary>
        /// Throws an invalid operation exception when the condition does not meet the requirement
        /// with error formatting support
        /// </summary>
        /// <param name="condition">The condition to test</param>
        /// <param name="format">The message to output when the condition is not true as a format string</param>
        /// <param name="args">The arguments</param>
        public static void RequireTrue(bool condition, string format, params Object[] args)
        {
            RequireTrue(condition, string.Format(format, args));
        }

        /// <summary>
        /// Throws an argument null exception when the required object is null
        /// </summary>
        /// <param name="value">The value to test</param>
        /// <param name="name">The name of the object instance or property</param>
        public static void RequireNotNull(object value, string name, TraceSource traceSource = null)
        {
            if (null == value)
            {
                if (traceSource != null)
                {
                    traceSource.LogError("Required property of name: {0} is null", name);
                }

                throw new ArgumentNullException(name);
            }
        }

        /// <summary>
        /// Throws an argument null exception when the required string is null or empty
        /// </summary>
        /// <param name="value">The value to test</param>
        /// <param name="name">The name of the object instance or property</param>
        public static void RequireNotNullOrEmpty(string value, string name, TraceSource traceSource = null)
        {
            if (string.IsNullOrEmpty(value))
            {
                if (traceSource != null)
                {
                    traceSource.LogError("Required property of name: {0} is null or empty", name);
                }

                throw new ArgumentNullException(name);
            }
        }
    }
}
